#ifndef MITSUBISHIWND_H
#define MITSUBISHIWND_H

#include <QObject>
#include <QWidget>
#include <QSerialPortInfo>
#include "Modbus/ModbusRTU/serialport.h"
#include <QDateTime>
#include <QSettings>
#include <QStandardItemModel>
#include <QFile>
#include <QDir>
#include <QMessageBox>
#include <QFileDialog>
#include <QTimer>
#include <QTableView>
#include "Device/HttpInteractiveData/httpinteractivedata.h"

namespace MITSUBISHI_WND_TXRX_RESULT_COLUMNS
{
    enum {
        TIMESTAMP           ,
        STATUS              ,
        MODE                ,
        RAWDATA             ,
        CRC                 ,
        SLAVE_ADDR          ,
        FUNCTION            ,
        INFO                ,
        COUNT
    };
}
namespace MITSUBISHI_WND_TX_QUEUE_COLUMNS
{
    enum {
        ENABLE           ,
        HEX              ,
        ASCII           ,
        COMMENT          ,
        COUNT
    };
}

class MitsubishiWnd : public QWidget
{
    Q_OBJECT

public:

    struct ComPortSetting{

        QString cmbComPort;
        QString cmbBaudrate;
        QString cmbDataBits;
        QString cmbParity;
        QString cmbStopBits;
    };

    ComPortSetting mComPortSetting;
    explicit MitsubishiWnd(QString port,QString baud,QString dataBits,QString parity,QString stopBits,QWidget *parent = 0);
    ~MitsubishiWnd();
    static bool check_ModbusRTU_CRC16(QByteArray buf, quint16 &result);    
    static quint8 LSBUS_sum(QByteArray buf);

    static quint8 LSBUS_sum_new(QByteArray buf);
    static quint8 LSBUS_sum_rev(QByteArray buf);
    static QByteArray toHexString(QByteArray buf);

    void createConnection();

    void resetRxCount() { m_rxCount = 0; emit sgRxCountChanged(); }
    void resetTxCount() { m_txCount = 0; emit sgTxCountChanged(); }
    void resetErrorCount() { m_errorCount = 0; emit sgErrorCountChanged(); }
    void addRxCount() { m_rxCount++; emit sgRxCountChanged(); }
    void addTxCount() { m_txCount++; emit sgTxCountChanged(); }
    void addErrorCount() { m_errorCount++; emit sgErrorCountChanged(); }


    int onParseData_send(QStringList &parsedData, QByteArray data);
    int onParseData_receive(QStringList &parsedData, QByteArray data);
    int onParseData(QStringList &parsedData, QByteArray data,QByteArray info);

    void closeEvent(QCloseEvent * event);
    void addDataToTxRxResultModel(QStringList info);
    void addDataToTxPktQueueModel(QStringList parsedData);
    QByteArray makeMisubishiFxFrame(QByteArray startCode, QByteArray CommandCode, QByteArray startAddr,QByteArray numOfRegister,QByteArray endCode);
    QByteArray makeMisubishiFxFrame_OfWrite(QByteArray startCode, QByteArray CommandCode, QByteArray startAddr,QByteArray numOfRegister,QByteArray endCode);

    /**
     * @brief makeMisubishiFxWriteFrame
     * @param startCode
     * @param CommandCode
     * @param startAddr
     * @param numOfRegister
     * @param endCode
     * @return
     *向三菱PLC发送写命令
     */
    QByteArray makeMisubishiFxWriteFrame(QByteArray startCode, QByteArray CommandCode, QByteArray startAddr,QByteArray numOfRegister,QByteArray writeData,QByteArray endCode);

public slots:

    void onPortConnected();
    void onPortDisconnected();
    void onPortResponseTimeout();

    /*!
     * \brief onTryConnectPort
     * try connet to com port
     */
    void onTryConnectPort();
    void onCloseConnetPort();
    void onRecvedData(QByteArray data);
    void onSendedData(QByteArray data);
    void onRecvedErrorData(QByteArray data);

    void onCmbComportTextChanged(QString str);
    quint32 onCmbBaudrateTextChanged(QString str);
    quint32 onCmbDataBitsTextChanged(QString str);
    quint32 onCmbParityTextChanged(QString str);
    quint32 onCmbStopBitsTextChanged(QString str);

    void onLineDecimalChanged();    

    void onCmbSendCountTextChanged(QString str);
    void onChkAutoSendToggled(bool checked);
    void onChkIgnoreAckToggled(bool checked);    
    void onSetPortTimeOut();

    void onBtnScreenClearClicked();
    void removeModelTxRxResult();        
    void onErrorCountChanged();           

    /*!
     * \brief initPowerOn
     *上电初始化的一些命令
     */
    void initPowerOn();
    /*!
     * \brief onSendWriteProcessStatusCmd
     * \param mStartCode
     * \param mCommandCode
     * \param mStartAddr
     * \param mNumOfRegister
     * \param mEndCode
     * \param mplcMode
     *发送写工艺参数状态模块，不加入发送队列
     */
    void onSendWriteProcessStatusCmd     (QString mStartCode,QString mCommandCode,QString mStartAddr,QString mNumOfRegister,QString mEndCode,QString mplcMode);

    /*!
     * \brief onSendInitWriteCmd :
     * \param mStartCode
     * \param mCommandCode
     * \param mStartAddr
     * \param mNumOfRegister
     * \param mRriteData
     * \param mEndCode
     * \param mplcMode
     */
    void onSendInitWriteCmd(QString mStartCode,QString mCommandCode,QString mStartAddr,QString mNumOfRegister,QString mRriteData,QString mEndCode,QString mplcMode);
    void onSendCmd         (QString mStartCode,QString mCommandCode,QString mStartAddr,QString mNumOfRegister,QString mEndCode,QString mplcMode);

    void btnTxQueueFileOpenClicked()  ;
    void btnTxqueueFileSaveClicked()  ;        

    void onModelTxPktQueueDataChanged(QModelIndex topLeft, QModelIndex bottomRight);

    void onTimerAutoSendTimeout();
    void onModelTxResultRowInserted(const QModelIndex &parent, int first, int last);
    void onViewTxQueueDataSelectionCurrentRowChanged(const QModelIndex &current, const QModelIndex &previous);
    void sendModelTxPktQueue(int index );
    void onReadyEntered();
    void onReceiveWriteList(QStringList);
public slots:
    void getTransforWgt(WgtChanged);
    void writeLowpressStatus(bool);
    void writeAftercompactionStatus(bool);
    void writeChouXinGangStatus(bool);
    void writeMotorStatus(bool);
    void writeGaoYaPaiQiStatus(bool);

    void writeLowPressureCount(QString, QString);
    void writeHighPressureCount(QString, QString);
    void writeLowProtectDelaytime(QString, QString);
    void writeReliefPressureDelaytime(QString, QString);
    void writeLowPressurePaiqiDelaytime(QString, QString);
    void writeHighPressureBaoyaDelaytime(QString, QString);

    void writeReliefPressureDelaytime2_2(QString, QString);
    void writeHighPressurePaiqiDelaytime_2(QString, QString);
    void writeMoldingBaoyaDelaytime_2(QString, QString);
    void writeTopoutDelaytime_2(QString, QString);
    void writeReliefPressureDelaytime_2(QString, QString);
    void writeClearCount();//TODO 20180719


signals:
    void sgRxCountChanged();
    void sgTxCountChanged();
    void sgErrorCountChanged();
    void sgConnected(QString str);
    void sgDisconnected(QString str);
    void sendWriteList(QStringList);
    void toggleAutoSend(bool);
    void workStatus(QString);
    void objCount(QString);
    void sendProcessSelectionRawData(QString);//发送工艺选择 收到的原始值；
    void sendInputStatusRawData(QString);
    void sendOutputStatusRawData(QString);
    void sendDelay1RawData1(QString);
    void sendDelay1RawData2(QString);
    void sendDelay1RawData3(QString);
    void sendDelay1RawData4(QString);
    void sendDelay1RawData5(QString);
    void sendDelay1RawData6(QString);
    void sendDelay2RawData1(QString);
    void sendDelay2RawData2(QString);
    void sendDelay2RawData3(QString);
    void sendDelay2RawData4(QString);
    void sendDelay2RawData5(QString);

    void plcConnectStatus(bool);
protected:
    QString             m_receiveData;
    int                 m_position;    
protected:
    void toggleAutoSendFun(bool check);

    /*!
     * \brief getWarnValue
     * \return
     * 获取报警值
     */
    int getWarnValue();
    /*!
     * \brief setWarnValue 设置报警的值
     * \param value int型报警值
     */
    void setWarnValue(int value);

    void setAmmeterValue(float);

private:
    SerialPort*             m_port;
    QStandardItemModel*     m_modelTxPktQueue;
    QStandardItemModel*     m_modelTxRxResult;
    quint64                 m_rxCount;
    quint64                 m_txCount;
    quint64                 m_errorCount;
    quint64                 m_txRxResultMaxRow;
    QThread*                m_threadForSerial;

    QTimer*                 m_timerAutoSend;    
    QStringList             m_parsedSysData;
    QStringList             m_parsedWarnData;
    QStringList             m_ammeterData;//ammeter data
    /*!
     * \brief m_warnValue
     * 警报值
     */
    int                     m_warnValue;
    QTableView              *m_viewTxQueueData;
    QTableView              *m_viewTxRxResult;
    WgtChanged              m_WgtChanged;
};


#endif // MITSUBISHIWND_H
